import cgi
import datetime
import urllib
import operator
import webapp2
import urllib, json, math
from analysis import sentimentAnalysis, significantWordCounter, buzzExtraction
from webServices import twitterGetSearch, getGeoCode
from ValueObject import Tweet, Category, Buzz
from google.appengine.ext import db
from google.appengine.ext.webapp.util import run_wsgi_app
import jinja2
import re
import os

JINJA_ENVIRONMENT = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))

MAIN_PAGE_FOOTER_TEMPLATE = """\
    <html><body>
    <form action="/search" method="post">
      <div>term: <input name="term"></div>
      <div>geo location<input name="geo_location"></input></div>
      <div><input type="submit" value="Search"></div>
    </form>
    <hr>
  </body>
</html>
"""


def getTop5Tweets(json):
    tmp_tuples = {}
    result = []
    #significant word count
    for tweet in json["results"]: # tweet is a list of dictionaries
        buzzText = tweet["text"]
        tmp_tuples[significantWordCounter(buzzText)] = tweet #how many significant words are there in a buzz
        #sorting
    sorted_tmp_list = sorted(tmp_tuples.iteritems(), key=operator.itemgetter(0),
                             reverse=True)#Sort tuples in a list by the second tuple element in descending ordering

    #get top 5

    for i in range(5):
        if i >= len(sorted_tmp_list):
            break;
        tweet = sorted_tmp_list[i][1]
        tweet_obj = {}
        tweet_obj["from_user"] = tweet["from_user"]
        tweet_obj["text"] = tweet["text"]
        tweet_obj["profile_image_url"] = tweet["profile_image_url"]
        tweet_obj["from_user_name"] = tweet["from_user_name"]
        tweet_obj["created_at"] = tweet["created_at"]
        result.append(tweet_obj)

    return result


'''
Main Page
'''


class MainPage(webapp2.RequestHandler):
    def get(self):
        self.response.write(MAIN_PAGE_FOOTER_TEMPLATE)


'''
TwitterSearch
'''


class TwitterSearch(webapp2.RequestHandler):
    def post(self):
        # We set the same parent key on the 'Tweet' to ensure each top_tweet
        # is in the same entity group. Queries across the single entity group
        # will be consistent. However, the write rate to a single entity group
        # should be limited to ~1/second.

        template = JINJA_ENVIRONMENT.get_template('templates/index.html')

        category_term = self.request.get('term')
        geo_location = self.request.get('geo_location')
        #term already existed?
        category_id = category_term + geo_location
        category_term_k = db.Key.from_path('Category', category_term + geo_location)
        category_term_in_db = db.get(category_term_k)
        #Does not exist
        if category_term_in_db is None:
            category_obj = Category(key_name=category_id)
            category_obj.geoLoc = geo_location
            category_obj.term = category_term
            category_obj.put()#store category obj



            #GET 100*10 tweets
            results_per_page = 100
            tweet_text = ""
            for page in range(1, 10):
                category_tweets_json = twitterGetSearch(term=category_term,
                                                        geocode=getGeoCode(geo_location),
                                                        per_page=str(results_per_page),
                                                        page=str(page), result_type="recent")
                for tweet in category_tweets_json['results']:
                    tweet_text = tweet_text + tweet['text']

            #remove special words and symbols from tweet text
            reg_pattern = re.compile('http://t|./|http|co|RT|amp', re.IGNORECASE)
            tweet_text = reg_pattern.sub('', tweet_text)
            reg_pattern = re.compile(r"^[\w\d'-]+$")
            tweet_text = reg_pattern.sub('', tweet_text)
            tweet_text = tweet_text.strip(",!.;|/")
            #buzz extraction
            top_10_buzzes = buzzExtraction(tweet_text,category_term)
            buzz_obj_list = []
            buzz_tweets_dict = {}
            for buzz_term in top_10_buzzes:
                buzz_tweets_json = twitterGetSearch(term=buzz_term[0], geocode=getGeoCode(""),
                                                    per_page=str(results_per_page), page=str(1),
                                                    result_type="recent")

                #sentiment analysis for every buzz
                sentiment_score_map = map(sentimentAnalysis, [tweet['text'] for tweet in buzz_tweets_json['results']])

                if len(sentiment_score_map) == 0:
                    sentiment_avg_score = -9999
                else:
                    sentiment_avg_score = (sum(sentiment_score_map) / math.sqrt(len(sentiment_score_map)))
                if -2 < sentiment_avg_score < 2:
                    sentiment_level = "neutral"
                elif -4 < sentiment_avg_score < -2:
                    sentiment_level = "negative"
                elif -100 < sentiment_avg_score < -4:
                    sentiment_level = "very negative"
                elif 2 < sentiment_avg_score < 4:
                    sentiment_level = "positive"
                elif 100 > sentiment_avg_score > 4:
                    sentiment_level = "very positive"
                else:
                    sentiment_level = "UNKNOWN"

                #get top 5 tweets for every buzz
                top_5_tweets = getTop5Tweets(buzz_tweets_json)
                #store buzz obj
                buzz_obj = Buzz(parent=category_term_in_db, key_name=buzz_term[0])
                buzz_obj.category_id = category_id
                buzz_obj.buzz_id = category_id + buzz_term[0]
                buzz_obj.term = buzz_term[0]
                buzz_obj.sentiment = sentiment_level
                buzz_obj.put()
                #output term,sentiment_level

                #construct top_tweet obj and store them in Data store
                tweet_id = 0
                tweet_obj_list = []
                for top_tweet in top_5_tweets:
                    tweet_obj = Tweet(parent=buzz_obj, key_name=buzz_term[0] + str(tweet_id))
                    tweet_obj.buzz_id = buzz_obj.buzz_id
                    tweet_obj.text = top_tweet["text"]
                    tweet_obj.created_at = top_tweet["created_at"]
                    tweet_obj.profile_image_url = top_tweet["profile_image_url"]
                    tweet_obj.from_user = top_tweet["from_user"]
                    tweet_obj.from_user_name = top_tweet["from_user_name"]
                    tweet_obj.location = geo_location
                    tweet_obj.put()
                    tweet_obj_list.append(tweet_obj)
                    tweet_id += 1

                buzz_tweets_dict[buzz_obj.term] = tweet_obj_list
                buzz_obj_list.append(buzz_obj)

            template_values = {
                'cached': False,
                'buzz_obj_list': buzz_obj_list,
                'buzz_tweets_dict': buzz_tweets_dict,
                'term': category_term,
                'geo_location': geo_location,
            }
            self.response.write(template.render(template_values))
        #existed
        else:
            buzz_obj_list = []
            buzz_tweets_dict = {}
            query_for_buzzes = db.GqlQuery("SELECT * FROM Buzz " +
                                           "WHERE category_id = :1 ",
                                           category_id)
            #output term,sentiment_level

            for buzz_obj in query_for_buzzes.run():
                query_for_tweets = db.GqlQuery("SELECT * FROM Tweet " +
                                               "WHERE buzz_id = :1 ",
                                               buzz_obj.buzz_id)
                tweet_obj_list = []
                for tweet_obj in query_for_tweets.run():
                    tweet_obj_list.append(tweet_obj)

                buzz_tweets_dict[buzz_obj.term] = tweet_obj_list
                buzz_obj_list.append(buzz_obj)

            template_values = {
                'cached': True,
                'buzz_obj_list': buzz_obj_list,
                'buzz_tweets_dict': buzz_tweets_dict,
                'term': category_term,
                'geo_location': geo_location,
            }
            self.response.write(template.render(template_values))


'''
Main
/Users/Work/Documents/workspace/bin/google_appengine/dev_appserver.py
'''

app = webapp2.WSGIApplication([('/', MainPage),
                               ('/search', TwitterSearch)],
                              debug=True)


